package com.lifeverse.entity;

import com.lifeverse.entity.enums.MetricType;
import com.lifeverse.entity.enums.MetricStatus;
import jakarta.persistence.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;
import lombok.Builder;

import java.math.BigDecimal;
import java.time.LocalDateTime;

/**
 * 性能指标实体
 * 记录系统各种性能指标数据
 */
@Entity
@Table(name = "performance_metrics", indexes = {
    @Index(name = "idx_performance_metric_name", columnList = "metric_name"),
    @Index(name = "idx_performance_metric_type", columnList = "metric_type"),
    @Index(name = "idx_performance_metric_timestamp", columnList = "measured_at"),
    @Index(name = "idx_performance_metric_component", columnList = "component_name"),
    @Index(name = "idx_performance_metric_status", columnList = "status")
})
@Data
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class PerformanceMetric extends BaseEntity {
    
    /**
     * 指标名称
     */
    @Column(name = "metric_name", nullable = false, length = 100)
    private String metricName;
    
    /**
     * 指标类型
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "metric_type", nullable = false, length = 30)
    private MetricType metricType;
    
    /**
     * 指标值
     */
    @Column(name = "metric_value", nullable = false, precision = 15, scale = 4)
    private BigDecimal metricValue;
    
    /**
     * 指标单位
     */
    @Column(name = "unit", length = 20)
    private String unit;
    
    /**
     * 组件名称
     */
    @Column(name = "component_name", length = 100)
    private String componentName;
    
    /**
     * 实例ID
     */
    @Column(name = "instance_id", length = 50)
    private String instanceId;
    
    /**
     * 测量时间
     */
    @Column(name = "measured_at", nullable = false)
    private LocalDateTime measuredAt;
    
    /**
     * 指标状态
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "status", nullable = false, length = 20)
    private MetricStatus status;
    
    /**
     * 最小阈值
     */
    @Column(name = "threshold_min", precision = 15, scale = 4)
    private BigDecimal thresholdMin;
    
    /**
     * 最大阈值
     */
    @Column(name = "threshold_max", precision = 15, scale = 4)
    private BigDecimal thresholdMax;
    
    /**
     * 警告阈值
     */
    @Column(name = "warning_threshold", precision = 15, scale = 4)
    private BigDecimal warningThreshold;
    
    /**
     * 临界阈值
     */
    @Column(name = "critical_threshold", precision = 15, scale = 4)
    private BigDecimal criticalThreshold;
    
    /**
     * 标签（JSON格式）
     */
    @Column(name = "tags", columnDefinition = "TEXT")
    private String tags;
    
    /**
     * 指标描述
     */
    @Column(name = "description", length = 500)
    private String description;
    
    /**
     * 采样间隔（秒）
     */
    @Column(name = "sample_interval")
    private Integer sampleInterval;
    
    /**
     * 聚合类型（AVG, SUM, MAX, MIN, COUNT等）
     */
    @Column(name = "aggregation_type", length = 20)
    private String aggregationType;
    
    /**
     * 聚合窗口（秒）
     */
    @Column(name = "aggregation_window")
    private Integer aggregationWindow;
    
    /**
     * 原始数据（JSON格式）
     */
    @Column(name = "raw_data", columnDefinition = "TEXT")
    private String rawData;
    
    /**
     * 相关指标ID
     */
    @Column(name = "related_metric_ids", length = 500)
    private String relatedMetricIds;
    
    /**
     * 是否为异常值
     */
    @Column(name = "is_anomaly")
    private Boolean isAnomaly;
    
    /**
     * 异常评分（0-1）
     */
    @Column(name = "anomaly_score", precision = 5, scale = 4)
    private BigDecimal anomalyScore;
    
    /**
     * 趋势方向（UP, DOWN, STABLE）
     */
    @Column(name = "trend_direction", length = 10)
    private String trendDirection;
    
    /**
     * 趋势强度（0-1）
     */
    @Column(name = "trend_strength", precision = 5, scale = 4)
    private BigDecimal trendStrength;
    
    /**
     * 创建性能指标的静态方法
     */
    public static PerformanceMetric create(String metricName, MetricType metricType, 
                                         BigDecimal metricValue, String unit, 
                                         String componentName) {
        return PerformanceMetric.builder()
                .metricName(metricName)
                .metricType(metricType)
                .metricValue(metricValue)
                .unit(unit)
                .componentName(componentName)
                .measuredAt(LocalDateTime.now())
                .status(MetricStatus.NORMAL)
                .isAnomaly(false)
                .build();
    }
    
    /**
     * 检查指标是否超出阈值
     */
    public boolean isOutOfThreshold() {
        if (thresholdMin != null && metricValue.compareTo(thresholdMin) < 0) {
            return true;
        }
        if (thresholdMax != null && metricValue.compareTo(thresholdMax) > 0) {
            return true;
        }
        return false;
    }
    
    /**
     * 检查指标是否处于警告状态
     */
    public boolean isWarning() {
        return warningThreshold != null && metricValue.compareTo(warningThreshold) >= 0;
    }
    
    /**
     * 检查指标是否处于临界状态
     */
    public boolean isCritical() {
        return criticalThreshold != null && metricValue.compareTo(criticalThreshold) >= 0;
    }
    
    /**
     * 更新指标状态
     */
    public void updateStatus() {
        if (isCritical()) {
            this.status = MetricStatus.CRITICAL;
        } else if (isWarning()) {
            this.status = MetricStatus.WARNING;
        } else if (isOutOfThreshold()) {
            this.status = MetricStatus.ABNORMAL;
        } else {
            this.status = MetricStatus.NORMAL;
        }
    }
    
    /**
     * 设置阈值
     */
    public PerformanceMetric withThresholds(BigDecimal min, BigDecimal max, 
                                          BigDecimal warning, BigDecimal critical) {
        this.thresholdMin = min;
        this.thresholdMax = max;
        this.warningThreshold = warning;
        this.criticalThreshold = critical;
        updateStatus();
        return this;
    }
    
    /**
     * 设置异常信息
     */
    public PerformanceMetric withAnomalyInfo(Boolean isAnomaly, BigDecimal anomalyScore) {
        this.isAnomaly = isAnomaly;
        this.anomalyScore = anomalyScore;
        return this;
    }
    
    /**
     * 设置趋势信息
     */
    public PerformanceMetric withTrendInfo(String trendDirection, BigDecimal trendStrength) {
        this.trendDirection = trendDirection;
        this.trendStrength = trendStrength;
        return this;
    }
}